home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-11
/
exoapi.zip
/
INT13.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-06-05
|
6KB
|
219 lines
;*****************************************************************************
;** INT13.ASM
;**
;** This is a sample of calling real-mode interrupt functions with ExoSpace.
;**
;** by J. David Reynolds
;**
;** This code is released to the public domain.
;**
;** requires MASM 6.0 or above
;** tab spacing = 3
;**
;*****************************************************************************
.MODEL LARGE, C
.286 ; safe to assume with ExoSpace
FARPTR TYPEDEF FAR PTR
INT13_READ equ 2
INT13_WRITE equ 3
INT13_VERIFY equ 4
INT13_FORMAT equ 5
; ExoSpace register structure for ExoRMInterrupt()
EXOREGS STRUCT
wDS WORD ?
wES WORD ?
wDI WORD ?
wSI WORD ?
wBP WORD ?
wSP WORD ?
wBX WORD ?
wDX WORD ?
wCX WORD ?
wAX WORD ?
EXOREGS ENDS
; ExoSpace API functions
_xalloclow PROTO FAR C, _wBytes:WORD
_xfreelow PROTO FAR C, _pPtr:FARPTR
ExoRealPtr PROTO FAR C, _pPtr:FARPTR
ExoRMInterrupt PROTO FAR C, _wInt:WORD, _regInRegs:FARPTR, \
_regOutRegs:FARPTR
.DATA
.CODE
;*****************************************************************************
;** void Int13()
;**
;** This function is a direct replacement for the instruction:
;** int 13h
;** for functions 2, 3, 4, and 5 only.
;**
;** Interrupt 13h is not supported by ExoSpace directly, so if one of its
;** functions is called which requires or returns a pointer to a buffer,
;** special handling is required. If no pointers are involved, nothing extra
;** needs to be done.
;**
;** This sample replacement only handles functions 2, 3, 4, and 5. These
;** are the read, write, verify, and format calls for floppy disks. Some
;** other interrupt 13h functions, such as 8 (get current drive parameters),
;** also need special handling if they are called directly from protected
;** mode.
;**
;*****************************************************************************
Int13 PROC FAR C
LOCAL _wAX:WORD, \
_wBufLen:WORD
LOCAL _pProtBuf:FARPTR, \
_pRealBuf:FARPTR, \
_pRealPtr:FARPTR
LOCAL _regRegs:EXOREGS
; only handles functions 2, 3, 4, and 5
.IF ( ( ah >= INT13_READ ) && ( ah <= INT13_FORMAT ) )
; save needed registers and pointers
mov _wAX, ax ; save function number (in ah)
mov _regRegs.wAX, ax ; save registers for int 13h call
mov _regRegs.wCX, cx
mov _regRegs.wDX, dx
mov WORD PTR _pProtBuf[2], es ; save pointer to protected-mode buffer
mov WORD PTR _pProtBuf[0], bx
mov WORD PTR _pRealBuf[2], es ; assume it's already in low memory
mov WORD PTR _pRealBuf[0], bx
; see if buffer is already in low memory by getting a real-mode pointer
; to buffer
INVOKE ExoRealPtr, _pProtBuf
; test for null pointer (meaning buffer is in extended memory)
.IF ( ( dx == 0 ) && ( ax == 0 ) )
; copy memory from protected-mode buffer to real-mode buffer
.IF ( BYTE PTR _wAX[1] == INT13_FORMAT )
mov _wBufLen, 512
.ELSE
mov ax, _wAX ; al=number of sectors
shl ax, 9 ; multiply by 512 to get bytes
mov _wBufLen, ax
.ENDIF
; allocate low memory
INVOKE _xalloclow, _wBufLen
; test for null pointer (meaning allocation failed)
.IF ( ( dx == 0 ) && ( ax == 0 ) )
mov ah, 0BBh ; int 13h undefined error code
stc
jmp ReturnPoint
.ELSE
mov WORD PTR _pRealBuf[2], dx
mov WORD PTR _pRealBuf[0], ax
.ENDIF
; only copy to real-mode buffer if writing or formatting
.IF ( ( BYTE PTR _wAX[1] == INT13_WRITE ) || \
( BYTE PTR _wAX[1] == INT13_FORMAT ) )
push si
push di
push ds
lds si, _pProtBuf
les di, _pRealBuf
mov cx, _wBufLen
shr cx, 1 ; always a multiple of 512 bytes
rep movsw
pop ds
pop di
pop si
.ENDIF
; get real-mode pointer to buffer
INVOKE ExoRealPtr, _pRealBuf
.ENDIF
; save real-mode pointer to buffer
mov WORD PTR _pRealPtr[2], dx
mov WORD PTR _pRealPtr[0], ax
; set up rest of register structure
mov ax, WORD PTR _pRealPtr[2]
mov _regRegs.wES, ax
mov ax, WORD PTR _pRealPtr[0]
mov _regRegs.wBX, ax
; call real-mode interrupt
INVOKE ExoRMInterrupt, 13h, ADDR _regRegs, ADDR _regRegs
push ax ; flags are returned in ax
popf
pushf ; save flags
; see if buffer was already in low memory
mov dx, WORD PTR _pProtBuf[2]
mov ax, WORD PTR _pProtBuf[0]
.IF ( ( dx != WORD PTR _pRealBuf[2] ) || \
( ax != WORD PTR _pRealBuf[0] ) )
; only copy back to protected-mode buffer if reading
.IF ( BYTE PTR _wAX[1] == INT13_READ )
push ds
push si
push di
lds si, _pRealBuf
les di, _pProtBuf
mov cx, _wBufLen
shr cx, 1 ; always a multiple of 512 bytes
rep movsw
pop di
pop si
pop ds
.ENDIF
; free low memory
INVOKE _xfreelow, _pRealBuf
.ENDIF
mov ax, _regRegs.wAX ; save return register values
mov cx, _regRegs.wCX
mov dx, _regRegs.wDX
mov es, WORD PTR _pProtBuf[2]
mov bx, WORD PTR _pProtBuf[0]
popf ; restore flags
.ELSE
; is not function 2, 3, 4, or 5, so just call int 13h in protected mode
int 13h
.ENDIF
ReturnPoint:
ret
Int13 ENDP
END